package image;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

public class ImageFixer
{
  public static void main(String args[])
  {
    if(args.length < 2)
    {
      System.out.println("args: <input> <output>");
      System.exit(1);
    }
    BufferedImage bimage = null;
    try {
      bimage = getImageFromFile(args[0]);
    } catch(Exception e) {
      e.printStackTrace();
    }
    bimage = cropToFace(bimage);
    save(bimage, args[1]);
  }

  public static BufferedImage getImageFromFile(String filename) throws IOException
  {
    File input = new File(filename);
    return ImageIO.read(input);
  }

  public static BufferedImage bufferImage(Image image, int width, int height)
  {
    BufferedImage bf = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
    Graphics2D g = bf.createGraphics();
    g.drawImage(image, null, null);
    return bf;
  }

  public static void drawFeaturePoints(BufferedImage bimage)
  {
    int width = bimage.getWidth();
    int height = bimage.getHeight();
    int dropHeight = height / 10;
    int midWidth = width / 2;
    int midHeight = height / 2;
    int red = 0xff << 16;
    for(int x = -1;x < 2;x++)
      for(int y = -1;y < 2;y++)
        bimage.setRGB(midWidth + x, midHeight + y + dropHeight, red);
    int thirdHeight = height / 3;
    int thirdWidth = width / 3;
    for(int x = thirdWidth;x <= thirdWidth*2;x++)
    {
      bimage.setRGB(x, thirdHeight + dropHeight, red);
      bimage.setRGB(x, thirdHeight + 1 + dropHeight, red);
    }
  }

  public static BufferedImage cropToFace(BufferedImage src)
  {
    return cropToFace(src, 0, 0);
  }

  public static BufferedImage cropToFace(BufferedImage src, int xOffset, int yOffset)
  {
    int width, height, x, y;
    width = 310;
    height = 380;
    x = 165;
    y = 45;
    BufferedImage dest = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
    Graphics2D g = dest.createGraphics();
    g.drawImage(src, 0, 0, width, height, x + xOffset, y + yOffset, x + width + xOffset, y + height + yOffset, null);
    g.dispose();
    return dest;
  }

  public static void imageToVector(BufferedImage image, double[] vector)
  {
    for(int x = 0;x < image.getWidth();x++)
    {
      for(int y = 0;y < image.getHeight();y++)
      {
        vector[x * image.getHeight() + y] = (double)getGray(image, x, y);
      }
    }
    //normalizeVector(vector);
  }

  public static void normalizeVector(double[] vector)
  {
    double mean = 0;
    for(int i = 0;i < vector.length;i++) {
      mean += vector[i];
    }
    mean /= vector.length;
    for(int i = 0;i < vector.length;i++) {
      vector[i] -= mean;
    }
  }

  public static BufferedImage resizeImage(BufferedImage image, int width, int height)
  {
    Image tmpImg = image.getScaledInstance(width, height, Image.SCALE_FAST);
    return bufferImage(tmpImg, width, height);
  }

  public static void save(BufferedImage image, String imageName)
  {
    try
    {
      ImageIO.write(image, "jpg", new File(imageName));
    }
    catch(Exception e)
    {
        System.err.println("image save failed in ImageFixer");
      //System.out.println(e);
    }
  }

  public static int getGray(BufferedImage image, int x, int y)
  {
    int rgb = image.getRGB(x, y);
    int blue = rgb & 0xff;
    int green = (rgb >> 8) & 0xff;
    int red = (rgb >> 16) & 0xff;
    return (blue * 1140 + green * 5870 + red * 2989) / 10000;
  }

  public static void toGray(BufferedImage image)
  {
    for(int x = 0;x < image.getWidth();x++)
    {
      for(int y = 0;y < image.getHeight();y++)
      {
        int gray = getGray(image, x, y);
        image.setRGB(x, y, gray | (gray << 8) | (gray << 16));
      }
    }
  }
}
